package eScrum.panels;

import java.util.Arrays;
import java.util.List;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.validation.EqualPasswordInputValidator;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.IValidator;
import org.apache.wicket.validation.ValidationError;

import eScrum.entities.User;
import eScrum.entities.UserRole;
import eScrum.entities.UserStatus;
import eScrum.services.UserService;
import eScrum.utils.EncryptionUtil;



public class CreateUserPopUpPanel  extends Panel {

	public class EmailValidator implements IValidator<String> {
		private static final long serialVersionUID = 1L;

		public void validate(IValidatable<String> validatable) {
			String email = validatable.getValue();
			if (email.matches("[\\w\\.\\-]+@[\\w\\-]+\\.\\w{2,3}\\.?\\w*")) {
			} else {
				validatable.error(new ValidationError().setMessage(getString("emailValidation")));
			}
		}

	}

	public class UsernameValidator implements IValidator<String> {
		private static final long serialVersionUID = 1L;

		public void validate(IValidatable<String> validatable) {
			String user = validatable.getValue();
			// if (user.split("\\w").length != 0) {
			// validatable.error(new
			// ValidationError().setMessage(getString("usernameValidation")));
			// }

			if (user.length() < 2 || user.length() > 15) {
				validatable.error(new ValidationError().setMessage(getString("usernameLength")));
			}
		}
	}

	public class PasswordValidator implements IValidator<String> {
		private static final long serialVersionUID = 1L;

		public void validate(IValidatable<String> validatable) {
			String pass = validatable.getValue();
			if (user.getRole() == UserRole.ADMIN) {
				if (pass.length() < 5 || pass.length() > 15) {
					validatable.error(new ValidationError().setMessage(getString("validPasswords1")));
				}
			} else if (pass.length() < 6 || pass.length() > 15) {
				validatable.error(new ValidationError().setMessage(getString("validPasswords2")));
			}
		}
	}

	private static final long serialVersionUID = 1L;

	@SpringBean
	private UserService userService;

/*	@SpringBean
	private DoctorService docsService;*/

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

/*	@SpringBean
	private MailManager mailManager;*/

	private User user;

	private DropDownChoice<Object> roleDropDownChoice;
	private TextField<String> emailTextField;
	private long userId;

	private FeedbackPanel feedbackPanel;

	private String pass;
	private String pass2;

/*	public void setMailManager(MailManager mailManager) {
		this.mailManager = mailManager;
	}*/

	public CreateUserPopUpPanel(String panelid, final long userId) {
		super(panelid);
		this.userId = userId;
		feedbackPanel = new FeedbackPanel("feedback");
		try {
			initUser();
		} catch (Exception e) {
			reportUnexpectedException(e);
			user = new User();
		}
		CompoundPropertyModel<User> userModel = new CompoundPropertyModel<User>(user);
		Form<User> userForm = new Form<User>("addUserForm", userModel);
		userForm.setOutputMarkupId(true);
		feedbackPanel.setOutputMarkupId(true);
		// first name
		// NameValidator nameValidator = new NameValidator();
		final TextField<String> firstnameTextField = new RequiredTextField<String>("firstname", userModel.<String> bind("firstName"));
		// firstnameTextField.add(nameValidator);
		userForm.add(firstnameTextField);
		// last name
		final TextField<String> lastnameTextField = new RequiredTextField<String>("lastname", userModel.<String> bind("lastName"));
		// lastnameTextField.add(nameValidator);
		userForm.add(lastnameTextField);
		// username
		final TextField<String> usernameTextField = new RequiredTextField<String>("username", userModel.<String> bind("username"));
		usernameTextField.add(new UsernameValidator());
		userForm.add(usernameTextField);
		// password
		final TextField<String> passwordTextField = new PasswordTextField("password", userModel.<String> bind("password"));
		passwordTextField.add(new PasswordValidator());
		userForm.add(passwordTextField);
		pass = passwordTextField.getValue();
		// confirm password
		final TextField<String> confirmPasswordTextField = new PasswordTextField("confirmPassword", userModel.<String> bind("password"));
		userForm.add(confirmPasswordTextField);
		userForm.add(new EqualPasswordInputValidator(passwordTextField, confirmPasswordTextField));
		// email
		emailTextField = new RequiredTextField<String>("email", userModel.<String> bind("email"));
		emailTextField.add(new EmailValidator());
		userForm.add(emailTextField);
		emailTextField.setRequired(false);
		// user role
		final List<UserRole> roles = Arrays
				.asList(new UserRole[] { UserRole.ADMIN, UserRole.DEVELOPER, UserRole.POWERUSER, UserRole.ClASSICUSER });
		roleDropDownChoice = new DropDownChoice<Object>("role", roles);
		userForm.add(roleDropDownChoice);
		// user status
		final List<UserStatus> status = Arrays.asList(new UserStatus[] { UserStatus.ACTIVE, UserStatus.SUSPENDED });
		userForm.add(new DropDownChoice<Object>("status", status));
		userForm.add(feedbackPanel);

		// Containers for mandatory/not mandatory labels
		// Password and Confirm Password labels mandatory on create user
		WebMarkupContainer passwordCreateUserContainer = new WebMarkupContainer("passwordCreateUserContainer") {
			@Override
			public boolean isVisible() {
				if (userId > 0) {
					return false;
				}
				return true;
			}
		};
		WebMarkupContainer passwordEditUserContainer = new WebMarkupContainer("passwordEditUserContainer") {
			@Override
			public boolean isVisible() {
				if (userId > 0) {
					return true;
				}
				return false;
			}
		};

		WebMarkupContainer confirmPasswordCreateUserContainer = new WebMarkupContainer("confirmPasswordCreateUserContainer") {
			@Override
			public boolean isVisible() {
				if (userId > 0) {
					return false;
				}
				return true;
			}
		};

		WebMarkupContainer confirmPasswordEditUserContainer = new WebMarkupContainer("confirmPasswordEditUserContainer") {
			@Override
			public boolean isVisible() {
				if (userId > 0) {
					return true;
				}
				return false;
			}
		};

		userForm.add(passwordCreateUserContainer);
		userForm.add(passwordEditUserContainer);
		userForm.add(confirmPasswordCreateUserContainer);
		userForm.add(confirmPasswordEditUserContainer);

		if (userId > 0) {

			passwordTextField.setRequired(false);
			confirmPasswordTextField.setRequired(false);
			roleDropDownChoice.setEnabled(false);
		}
		roleDropDownChoice.setRequired(true);
		userForm.add(new AjaxButton("closeOk", userForm) {
			@Override
			protected void onSubmit(AjaxRequestTarget target, Form<?> registerForm) {
				try {
					pass2 = passwordTextField.getValue();
					doSubmitUser(target);
					if (pass2 == "") {
						doSubmitUser(target);
					}

				} catch (Exception e) {
					reportUnexpectedException(e);
				}
			}

			@Override
			protected void onError(AjaxRequestTarget target, Form<?> form) {
				target.add(feedbackPanel);
			}
		});

		userForm.add(new AjaxLink<Void>("closeCancel") {
			private static final long serialVersionUID = 1L;

			@Override
			public void onClick(AjaxRequestTarget target) {
				target.add(feedbackPanel);
				ModalWindow.closeCurrent(target);
			}

		});
		add(userForm);
	}

	private void initUser() {
		if (userId < 0) {
			user = new User();
		} else {
			user = userService.findById(userId);
		}
	}

	public void refreshData(AjaxRequestTarget target) {
	}

	private void doSubmitUser(AjaxRequestTarget target) {
		if (userId < 0) {
			if (userService.findUserByUserName(user.getUsername()) != null) {
				error(getString("userAlreadyExists"));
				target.add(feedbackPanel);

			} else {
				userService.saveOrUpdate(user);
				user.setPassword(EncryptionUtil.crypt(user.getPassword()));
				userService.saveOrUpdate(user);
				ModalWindow.closeCurrent(target);
				refreshData(target);
			}
		} else if (userId > 0) {
			try {
				if (pass2 == "") {
					user.setPassword(pass);
					userService.saveOrUpdate(user);
					// user.setPassword(EncryptionUtil.crypt(user.getPassword()));
					// userService.saveOrUpdate(user);
				} else {
					userService.saveOrUpdate(user);
					user.setPassword(EncryptionUtil.crypt(user.getPassword()));
					userService.saveOrUpdate(user);
				}
				ModalWindow.closeCurrent(target);
				refreshData(target);
			} catch (Exception e) {
				e.printStackTrace();
				error(e.getMessage());
				target.add(feedbackPanel);
			}

		}

	}

	protected void reportUnexpectedException(Exception e) {
		e.printStackTrace();
		error(getString("unexpectedError") + (e.getMessage() == null ? getString("unknown") : e.getMessage()));
	}
}


